package com.jinke.api.modules.third.changYunShip.util;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.jinke.api.common.annotation.Apilog;
import com.jinke.api.common.util.CommonUtil;
import com.jinke.api.modules.app.util.MathUtil;
import com.jinke.api.modules.third.changYunShip.model.request.ChangYunShipCreateOrder;
import com.jinke.api.modules.third.changYunShip.model.request.ChangYunShipPrice;
import com.jinke.api.modules.third.ezeeship.model.request.EstimateRateRequest;
import com.jinke.api.modules.third.ezeeship.util.EzeeShipUtil;
import com.jinke.api.modules.ums.model.Channel;
import com.jinke.api.modules.ums.vo.UserChannelVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * @author huang
 * @data 2024-05-07
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ChangYunShipUtils {
    private  static   final String API_KEY = "38c3e307-22d6-42c5-ab9b-649e8ba595b5";
    public static final String APPLY_REFUND = "https://admin.cangyunship.com/api/external/order/apply-refund";

    /**
     * Post
     *
     * @param url  路径
     * @param body 请求体
     * @return 结果
     * @throws IOException io
     */
    public    String sendPostRequest(String url, String body) throws IOException {
        String seq = CommonUtil.getOrderNo();
        log.info("send:,{}", seq);
        HttpURLConnection connection = null;
        try {
            // 创建连接
            URL apiUrl = new URL(url);
            if ("true".equals(System.getenv("local"))) {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 7890));
                connection = (HttpURLConnection) apiUrl.openConnection(proxy);
            } else {
                connection = (HttpURLConnection) apiUrl.openConnection();
            }

            connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Auth", API_KEY);
            connection.setDoOutput(true);

            // 写入请求体
            try (OutputStream outputStream = connection.getOutputStream()) {
                outputStream.write(body.getBytes("UTF-8"));
            }

            int responseCode = connection.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST) {
                // 获取错误消息体
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) {
                    StringBuilder errorResponse = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        errorResponse.append(line);
                    }
                    log.error("Error response :  {}, {}", seq, errorResponse);
                    return errorResponse.toString();
                }
            } else {
                // 获取正常响应
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    log.info("rec :  {}, {}", seq, response);
                    return response.toString();
                }
            }
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    /**
     * put
     *
     * @param url  路径
     * @param body 请求体
     * @return 结果
     * @throws IOException io
     */
    public    String sendPutRequest(String url, String body) throws IOException {
        String seq = CommonUtil.getOrderNo();
        log.info("send :  {}, {}", seq);
        HttpURLConnection connection = null;
        try {
            // 创建连接
            URL apiUrl = new URL(url);
            if ("true".equals(System.getenv("local"))) {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 7890));
                connection = (HttpURLConnection) apiUrl.openConnection(proxy);
            } else {
                connection = (HttpURLConnection) apiUrl.openConnection();
            }

            connection = (HttpURLConnection) apiUrl.openConnection();
            connection.setRequestMethod("PUT");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Auth", API_KEY);
            connection.setDoOutput(true);

            // 写入请求体
            try (OutputStream outputStream = connection.getOutputStream()) {
                outputStream.write(body.getBytes("UTF-8"));
            }

            int responseCode = connection.getResponseCode();

            if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST) {
                // 获取错误消息体
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) {
                    StringBuilder errorResponse = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        errorResponse.append(line);
                    }
                    log.error("Error response :  {}, {}", seq, errorResponse);
                    return errorResponse.toString();
                }
            } else {
                // 获取正常响应
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    log.info("rec :  {}, {}", seq, response);
                    return response.toString();
                }
            }
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    /**
     * Get
     *
     * @param url l路径
     * @return 响应结果
     * @throws IOException io
     */
    private    String sendGetRequest(String url) throws IOException {
        HttpURLConnection connection = null;
        try {
            String seq = CommonUtil.getOrderNo();
            log.info("send :  {}, {}", seq, url);
            URL apiUrl = new URL(url);
            if ("true".equals(System.getenv("local"))) {
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 7890));
                connection = (HttpURLConnection) apiUrl.openConnection(proxy);
            } else {
                connection = (HttpURLConnection) apiUrl.openConnection();
            }

            connection.setRequestMethod("GET");
            connection.setRequestProperty("Content-Type", "application/json");
            connection.setRequestProperty("Auth", API_KEY);
            // 获取响应
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                log.info("rec :  {}, {}", seq, response.toString());
                return response.toString();
            }
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
        }
    }

    /**
     * 估价
     */
    @Apilog(requestTypeName = "ChangYunShip-估价")
    public    String getPrice(EstimateRateRequest request) {
        String url = "https://admin.cangyunship.com/api/external/cost/estimate";
        try {
            String body = getPriceBody(request);
            log.info("--------ChangYunShip--------估价参数" + body);
            String response = sendPostRequest(url, body);
            log.info("------ChangYunShip----------估价返回结果" + response);
            return response;
        } catch (IOException e) {
            log.error("------ChangYunShip---------估价接口异常，订单id{},错误信息{}", request.getOrderId(), e.getMessage());
        }
        return Strings.EMPTY;
    }

    /**
     * 下单
     *
     * @return 响应结果
     */

    @Apilog(requestTypeName = "ChangYunShip-下单")
    public    String createOrder(EstimateRateRequest request) {
        String url = "https://admin.cangyunship.com/api/external/order/create";
        try {
            String body = createOrderBody(request);
            log.info("----------------------ChangYunShip----------------------下单参数,{}", body);
            String result = sendPostRequest(url, body);
            log.info("-----------------ChangYunShip--------------------下单返回参数,{}", result);
            return result;
        } catch (Exception e) {
            log.info("-------------ChangYunShip----------下单失败，{}", request.getOrderId());
            e.printStackTrace();
        }
        return Strings.EMPTY;
    }

    /**
     * 取消订单
     *
     * @param objectId
     * @param orderNo
     * @return result
     */
    @Apilog(requestTypeName = "ChangYunShip-取消")
    public String cancel(String objectId, String orderNo) {
        try {
            List<String> body = new ArrayList<>(1);
            body.add(objectId);
            String param = JSON.toJSONString(body);
            log.info("-----------------ChangYunShip取消订单----------------------{},{}", orderNo, param);
            String result = sendPutRequest(APPLY_REFUND, param);
            log.info("-----------------ChangYunShip取消响应----------------------{},{}", orderNo, result);
            return result;
        } catch (Exception e) {
            log.info("----------------ChangYunShip取消异常----------------------{},{}", orderNo, e.getMessage());
            e.printStackTrace();
        }
        return Strings.EMPTY;
    }

    /**
     * 组装下单参数
     *
     * @param request 请求参数
     * @return json
     */
    private    String createOrderBody(EstimateRateRequest request) {
        ChangYunShipCreateOrder order = new ChangYunShipCreateOrder();
        //获取渠道相关信息
        UserChannelVO userChannelVO = request.getUserChannelVO();
        Channel channel = userChannelVO.getChannel();
        order.setTransportChannelId("11");
        order.setTransportChannelTypeId(channel.getChannelCode());
        //发件人信息
        EstimateRateRequest.Address from = request.getFrom();
        order.setCityForSend(from.getCountryCode());
        order.setCountryForSend(from.getCity());
        order.setProvinceForSend(from.getStateCode());
        order.setNameForSend(from.getPersonName());
        order.setTelForSend(from.getPhone());
        order.setAddress1ForSend(from.getAddressLine1());
        order.setPostalCodeForSend(from.getZipCode());
        //收件人信息
        EstimateRateRequest.Address to = request.getTo();
        order.setCountryForReceive(to.getCountryCode());
        order.setIsResidence(ObjectUtils.isNotEmpty(to.getIsResidential()) && to.getIsResidential() ? "0" : "1");
        order.setCityForReceive(to.getCity());
        order.setProvinceForReceive(to.getStateCode());
        order.setNameForReceive(to.getPersonName());
        order.setTelForReceive(to.getPhone());
        order.setAddress1ForReceive(to.getAddressLine1());
        order.setPostalCodeForReceive(to.getZipCode());
        //包裹信息
        List<EstimateRateRequest.Parcel> parcels = request.getParcels();
        order.setPiece(parcels.size());
        for (EstimateRateRequest.Parcel parcel : parcels) {
            BigDecimal parcelLength = new BigDecimal(parcel.getLength());
            BigDecimal parcelHeight = new BigDecimal(parcel.getHeight());
            BigDecimal parcelWidth = new BigDecimal(parcel.getWidth());
            BigDecimal parcelWeight = new BigDecimal(parcel.getWeight());
            if ("cm".equals(parcel.getDistanceUnit())) {
                parcelLength = MathUtil.cm2in(parcelLength);
                parcelWidth = MathUtil.cm2in(parcelWidth);
                parcelHeight = MathUtil.cm2in(parcelHeight);
            }
            if ("kg".equals(parcel.getMassUnit())) {
                parcelWeight = MathUtil.kg2lb(parcelWeight);
            }
            order.setLength(order.getLength().add(parcelLength));
            order.setWidth(order.getWidth().add(parcelWidth));
            order.setHeight(order.getHeight().add(parcelHeight));
            order.setWight(order.getWight().add(parcelWeight));
            order.setIsSign(ObjectUtils.isNotEmpty(request.getExtra().getBatteryType()) ? "1" : "0");
            order.setSaturdaySend(ObjectUtils.isNotEmpty(request.getExtra().getIsStd()) && request.getExtra().getIsStd() ? "1" : "0");
            if (StringUtils.isNotEmpty(request.getExtra().getReference())) {
                order.setDescription(request.getExtra().getReference());
            }
            if (StringUtils.isNotEmpty(request.getExtra().getReference2())) {
                if (StringUtils.isNotEmpty(order.getDescription())) {
                    order.setDescription(order.getDescription() + "/" + request.getExtra().getReference2());
                } else {
                    order.setDescription(request.getExtra().getReference2());
                }
            }
        }
        return JSON.toJSONString(order);
    }


    /**
     * 估价参数组装
     *
     * @param request 请求参数
     * @return json
     */
    private    String getPriceBody(EstimateRateRequest request) {
        List<EstimateRateRequest.Parcel> parcels = request.getParcels();
        BigDecimal weight = new BigDecimal("0");
        BigDecimal height = new BigDecimal("0");
        BigDecimal width = new BigDecimal("0");
        BigDecimal length = new BigDecimal("0");
        for (EstimateRateRequest.Parcel parcel : parcels) {
            BigDecimal parcelLength = new BigDecimal(parcel.getLength());
            BigDecimal parcelHeight = new BigDecimal(parcel.getHeight());
            BigDecimal parcelWidth = new BigDecimal(parcel.getWidth());
            BigDecimal parcelWeight = new BigDecimal(parcel.getWeight());
            if ("cm".equals(parcel.getDistanceUnit())) {
                parcelLength = MathUtil.cm2in(parcelLength);
                parcelWidth = MathUtil.cm2in(parcelWidth);
                parcelHeight = MathUtil.cm2in(parcelHeight);
            }
            if ("kg".equals(parcel.getMassUnit())) {
                parcelWeight = MathUtil.kg2lb(parcelWeight);
            }
            length = length.add(parcelLength);
            height = height.add(parcelHeight);
            weight = width.add(parcelWeight);
            width = width.add(parcelWidth);
        }

        ChangYunShipPrice price = new ChangYunShipPrice();
        price.setZip(request.getTo().getZipCode());
        price.setZipForSend(request.getFrom().getZipCode());
        price.setIsSign(ObjectUtils.isNotEmpty(request.getExtra().getBatteryType()) ? "1" : "0");
        price.setSaturdaySend(ObjectUtils.isNotEmpty(request.getExtra().getIsStd()) && request.getExtra().getIsStd() ? "1" : "0");
        price.setWight(weight);
        price.setLength(length);
        price.setWidth(width);
        price.setHeight(height);
        return JSON.toJSONString(price);
    }
}
